package com.stormragetech.arthas.dispatcher;

import com.stormragetech.arthas.codec.ArthasHttpResponseEncodeHandler;
import com.stormragetech.arthas.common.annotation.ResponseType;
import com.stormragetech.arthas.common.constant.Constant;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpUtil;
import lombok.extern.log4j.Log4j2;

/**
 * description: Arthas channel handler, recieve request and response result
 *
 * @author: Xue Bin
 * @version: 1.0.0-SNAPSHOT
 */
@Log4j2
public class ArthasHttpHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {

        long start = System.currentTimeMillis();

        if (msg instanceof HttpRequest) {

            // initialize channel and request
            // cache the data to ThreadLocal
            //
            HttpRequest request = (HttpRequest) msg;
            DataCache.setData(msg);
            FullHttpResponse response = new ArthasProcessHandler().process();

            boolean keepAlive = HttpUtil.isKeepAlive(request);
            if (!keepAlive) {
                ctx.write(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                response.headers().set(Constant.CONNECTION, Constant.KEEP_ALIVE);
                ctx.write(response);
            }
            log.info("---------------------------------------------------------------");
            log.info("READ: {}", ctx.channel());
            log.info("URL: {}", request.uri().split("\\?")[0]);
            log.info("READ: complete | COST: {} | RESPONSE: {}", System.currentTimeMillis() - start, response.status());
            log.info("---------------------------------------------------------------\n\n");
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("netty handler http request occur error, excepion: {}", cause.getStackTrace());
        ctx.close();
    }
}
